﻿using System.Collections.Generic;
using Xpus.Website.Configuration;
using System.Web;
using System.Xml;
using System.Text.RegularExpressions;

namespace Xpus.Website.Utilities
{
	/// <summary>
	/// 用于提供各种正则表达式。
	/// </summary>
	public static class RegexUtility
	{
		#region 私有实现
		/// <summary>
		/// 用于存放所有的正则表达式。
		/// </summary>
		static Dictionary<string, Regex> _regexes = new Dictionary<string, Regex>();

		/// <summary>
		/// 初始化正则表达式工具。
		/// </summary>
		static RegexUtility()
		{
			LoadRegex();
		}

		/// <summary>
		/// 加载配置文件中的所有正则表达式。
		/// </summary>
		private static void LoadRegex()
		{
			string dataPathConfig = XpusConfigurationSection.Instance.Regex.DataPath;
			string dataPath = HttpContext.Current.Server.MapPath(dataPathConfig);

			XmlDocument xdoc = new XmlDocument();
			xdoc.Load(dataPath);
			XmlNodeList xnodes = xdoc.SelectNodes("regexes/regex");

			foreach(XmlNode xnode in xnodes)
			{
				XmlNode nameNode = xnode.SelectSingleNode("@name");
				XmlNode optionsNode = xnode.SelectSingleNode("@options");

				string name = nameNode.Value;
				string options = optionsNode.Value;
				string regex = xnode.InnerText;

				Regex reg = BuildRegex(options, regex);
				_regexes.Add(name, reg);
			}
		}

		/// <summary>
		/// 构造正则表达式。
		/// </summary>
		/// <param name="options">表示正则表达式的选项。</param>
		/// <param name="regex">正则表达式的模式文本。</param>
		/// <returns>构造好的正则表达式对象。</returns>
		private static Regex BuildRegex(string options, string regex)
		{
			RegexOptions opt = ParseRegexOptions(options);
			Regex reg = new Regex(regex, opt);
			return reg;
		}

		/// <summary>
		/// 从选项字符串中创建正则表达式选项。
		/// </summary>
		/// <param name="options">
		/// 表示正则表达式选项的字符串。<br/>
		///   - I：IgnoreCase<br/>
		///   - M：Multiline<br/>
		///   - E：ExplicitCapture<br/>
		///   - S：Singleline<br/>
		///   - W：IgnorePatternWhitespace<br/>
		///   - R：RightToLeft<br/>
		///   - C：CultureInvariant
		/// </param>
		/// <returns>构造好的选项。</returns>
		private static RegexOptions ParseRegexOptions(string options)
		{
			RegexOptions opt = RegexOptions.Compiled;

			foreach(char c in options)
			{
				switch(c)
				{
				case 'I':
				opt |= RegexOptions.IgnoreCase;
				break;
				case 'M':
				opt |= RegexOptions.Multiline;
				break;
				case 'E':
				opt |= RegexOptions.ExplicitCapture;
				break;
				case 'S':
				opt |= RegexOptions.Singleline;
				break;
				case 'W':
				opt |= RegexOptions.IgnorePatternWhitespace;
				break;
				case 'R':
				opt |= RegexOptions.RightToLeft;
				break;
				case 'C':
				opt |= RegexOptions.CultureInvariant;
				break;
				}
			}

			return opt;
		}
		#endregion

		#region 公共正则表达式项
		/// <summary>
		/// 根据正则表达式的名称获取正则表达式。
		/// </summary>
		/// <param name="name">正则表达式的名称。</param>
		/// <returns>具有指定名字的正则表达式对象。</returns>
		public static Regex GetRegex(string name)
		{
			if(_regexes.ContainsKey(name))
				return _regexes[name];
			else
				return null;
		}
		#endregion
	}
}
